package com.lich.controller;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import com.lich.entity.AppFunction;
import com.lich.entity.Department;
import com.lich.entity.Product;
import com.lich.entity.vo.FunctionStatisticResult;
import com.lich.entity.vo.Page;
import com.lich.entity.vo.Result;
import com.lich.service.AppFunctionService;
import com.lich.service.FunctionStatisticService;
import com.lich.service.ProductService;
import com.lich.util.ExcelUtil;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Controller
@RequestMapping("/appFunction")
public class AppFunctionController {

	@Resource
	AppFunctionService appFunctionService;
	@Resource
	ProductService productService;
	@Resource
	FunctionStatisticService functionStatisticService;
	private static Logger logger = LoggerFactory.getLogger(AppFunctionController.class);
	/**
	 * @description 添加APP
	 * @date 2016年8月31日
	 * @author luosf
	 * @param product
	 * @return
	 */
	@RequestMapping(value = "/add", method = RequestMethod.POST)
	public ModelAndView add(AppFunction appFunction) {
		Result<List<Department>> result = new Result<>();
		appFunction.setCreateTime(new Date());
		appFunction.setUpdateTime(new Date());
		try {
			if(appFunctionService.add(appFunction)>0){
				result.setSuccess(true);
				result.setMessage("添加App菜单成功");
			}else{
				result.setSuccess(false);
				result.setMessage("添加App菜单失败");
			}
		} catch (Exception e) {
			result.setSuccess(false);
			result.setMessage("添加App菜单失败");
			logger.error("添加App菜单失败 : "+e.getMessage());
		}
		return new ModelAndView(new MappingJackson2JsonView(), "result", result);
	}
	
	/**
	 * @description 删除
	 * @date 2016年8月31日
	 * @author luosf
	 * @param appFunction
	 * @return
	 */
	@RequestMapping(value = "/delete", method = RequestMethod.POST)
	public ModelAndView delete(AppFunction appFunction) {
		Result<List<Department>> result = new Result<>();
		try {
			List<AppFunction> deleteTree = new ArrayList<>();
			List<AppFunction> appFunctions = appFunctionService.findAll();
			getTree(deleteTree, appFunctions, appFunction.getId(), true, appFunction.getProductId());
			appFunctionService.deleteById(appFunction.getId());//删除当前节点
			for (AppFunction delApp : deleteTree) {//删除当前节点所有子节点
				appFunctionService.deleteById(delApp.getId());
			}
			result.setSuccess(true);
			result.setMessage("删除菜单成功");
		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccess(false);
			result.setMessage("删除菜单失败");
			logger.error("删除菜单失败 : "+e.getMessage());
		}
		return new ModelAndView(new MappingJackson2JsonView(), "result", result);
	}

	/**
	 * @description 更新
	 * @date 2016年8月31日
	 * @author luosf
	 * @param appFunction
	 * @return
	 */
	@RequestMapping(value = "/updateView", method = {RequestMethod.POST,RequestMethod.GET})
	public ModelAndView updateView(AppFunction appFunction) {
		Result<Map<String, Object>> result = new Result<>();
		Map<String, Object> params = new HashMap<String, Object>();
		try {
			appFunction = appFunctionService.selectById(appFunction.getId());
			params.put("appFunction", appFunction);
			result.setObject(params);
			result.setSuccess(true);
		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccess(false);
			result.setMessage("获取数据异常");
			logger.error("获取APP更新数据异常 : "+e.getMessage());
		}
		
		return new ModelAndView(new MappingJackson2JsonView(), "result", result);
	}

	
	/**
	 * @description 更新
	 * @date 2016年8月31日
	 * @author luosf
	 * @param appFunction
	 * @return
	 */
	@RequestMapping(value = "/update", method = {RequestMethod.POST,RequestMethod.GET})
	public ModelAndView update(AppFunction appFunction) {
		Result<List<Department>> result = new Result<>();
		StringBuffer message = new StringBuffer();
		try {
			int stat = 0;
			if(appFunction.getId() == null){
				appFunction.setCreateTime(new Date());
				appFunction.setUuid(UUID.randomUUID().toString());
				message.append("新增");
				stat = appFunctionService.add(appFunction);
			}else{
				appFunction.setUpdateTime(new Date());
				message.append("修改");
				stat = appFunctionService.update(appFunction);
			}
			if(stat>0){
				result.setSuccess(true);
				result.setMessage(message.append("App菜单成功").toString());
			}else{
				result.setSuccess(false);
				result.setMessage(message.append("App菜单失败").toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccess(false);
			result.setMessage("APP功能更新异常");
			logger.error("APP功能更新异常 : "+e.getMessage());
		}
		
		return new ModelAndView(new MappingJackson2JsonView(), "result", result);
	}

	/**
	 * @description 查看APP页面
	 * @date 2016年8月31日
	 * @author luosf
	 * @param pageParam
	 * @return
	 */
	@RequestMapping(value = "/list", method = {RequestMethod.POST,RequestMethod.GET})
	public ModelAndView getPage(Page<AppFunction> page,AppFunction appFunction) {
		Result<Page<AppFunction>> result = new Result<>();
		List<AppFunction> appFunctions = null;
		appFunction.setPage(page);
		//List<AppFunction> tree = new ArrayList<>();
		try {
			appFunctions = appFunctionService.getPage(appFunction);
			//getTree(tree, appFunctions, 1, true, appFunction.getProductId());
			page.setList(appFunctions);
			result.setObject(page);
			result.setSuccess(true);
			result.setMessage("获取产品数据成功");
		} catch (IllegalAccessException | InvocationTargetException e) {
			result.setSuccess(false);
			result.setMessage("获取产品数据失败");
			logger.error("获取产品数据异常 : "+e.getMessage());
		}
		
		return new ModelAndView("manager/app/list", "result", result);
	}
	
	/**
	 * @description 获取所有节点树
	 * @date 2016年8月31日
	 * @author luosf
	 * @param pageParam
	 * @return
	 */
	@RequestMapping(value = "/treeData", method = RequestMethod.POST)
	public ModelAndView treeData(Product product) {
		Result<JSONArray> result = new Result<>();
		List<AppFunction> appFunctions = null;
		try {
			appFunctions = appFunctionService.findAll();
			JSONArray jsonArray = new JSONArray();
			getTreeData(jsonArray,appFunctions,1,true,product.getId());
			result.setObject(jsonArray);
			result.setSuccess(true);
			result.setMessage("获取产品数据成功");
		} catch (IllegalAccessException | InvocationTargetException e) {
			result.setSuccess(false);
			result.setMessage("获取产品数据失败");
			logger.error("获取产品树结构异常 : "+e.getMessage());
		}
		
		return new ModelAndView(new MappingJackson2JsonView(), "result", result);
	}
	
	/**
	 * @description 递归获取所有子节点
	 * @date 2016年8月31日
	 * @author luosf
	 * @param jsonArray 组装数组
	 * @param appFunctions	数据源
	 * @param parentId 父节点
	 * @param cascade 是否有子节点
	 * @return
	 */
	private void getTreeData(JSONArray jsonArray, List<AppFunction> appFunctions,Integer parentId,boolean cascade,Integer productId){
		if(productId == null) return;//没有产品ID，直接返回
		for (int i=0; i<appFunctions.size(); i++){
			AppFunction app = appFunctions.get(i);
			if (app.getParentId()!=null && app.getParentId().equals(parentId) && app.getProductId()==productId){
				JSONObject json = new JSONObject();
				json.put("text", app.getName()+
						"  <button  style='margin-left:40px;' title='添加节点' onclick='add(this)'><span class='glyphicon glyphicon-plus'></span></button>"
						+" <button  style='margin-left:10px;' title='修改节点' onclick='itemOnclick(this)'><span class='glyphicon glyphicon-pencil'></button>"
						+ " <button style='margin-left:10px;' title='删除节点' onclick='deleteById(this)'><span class='glyphicon glyphicon-minus'></button>");
				json.put("nodeId", app.getId());
				json.put("id", app.getId());
				json.put("parentId", app.getParentId());
				if (cascade){
					// 判断是否还有子节点, 有则继续获取子节点
					for (int j=0; j<appFunctions.size(); j++){
						AppFunction child = appFunctions.get(j);
						if (child.getParentId()!=null && child.getParentId().equals(app.getId())  && child.getProductId()==productId){
							JSONArray childArr = new JSONArray();
							getTreeData(childArr, appFunctions, app.getId(), true,productId);
							json.put("nodes", childArr);
							break;
						}
					}
				}
				jsonArray.add(json);
			}
			
		}
	}
	
	/**
	 * @description 递归获取所有子节点
	 * @date 2016年8月31日
	 * @author luosf
	 * @param jsonArray 组装数组
	 * @param appFunctions	数据源
	 * @param parentId 父节点
	 * @param cascade 是否有子节点
	 * @return
	 */
	private void getTree(List<AppFunction> tree, List<AppFunction> appFunctions,Integer parentId,boolean cascade,Integer productId){
		if(productId == null) return;//没有产品ID，直接返回
		for (int i=0; i<appFunctions.size(); i++){
			AppFunction app = appFunctions.get(i);
			if (app.getParentId()!=null && app.getParentId().equals(parentId) && app.getProductId()==productId){
				tree.add(app);
				if (cascade){
					// 判断是否还有子节点, 有则继续获取子节点
					for (int j=0; j<appFunctions.size(); j++){
						AppFunction child = appFunctions.get(j);
						if (child.getParentId()!=null && child.getParentId().equals(app.getId())  && child.getProductId()==productId){
							getTree(tree, appFunctions, app.getId(), true,productId);
							break;
						}
					}
				}
			}
		}
	}
	
	@RequestMapping(value = "/export",method = {RequestMethod.POST,RequestMethod.GET})    
    public void exportExcel(HttpServletResponse response)     
    throws Exception {    
        List<AppFunction> list = appFunctionService.findAll(); 
        String[] header = {"id","名称","描述","创建时间"};
        String[] colunm = {"id","name","description","createTime"};
        HSSFWorkbook wb = new ExcelUtil<AppFunction>().export(list,AppFunction.class,header,colunm,response,"错误信息");    
   }  
	@RequestMapping(value = "/chart", method = RequestMethod.POST)
	public String chartPage() {
		return "manager/app/functionChart";
	}
	/**
	 * @description 获取指定产品某段时间内所有功能被使用的总数
	 * @date 2016年9月19日
	 * @author lich
	 * @param productId
	 * @param minDate
	 * @param maxDate
	 * @return
	 */
	@RequestMapping(value = "/statistic", method = RequestMethod.POST)
	public ModelAndView getStatistic(String productId, @DateTimeFormat(pattern = "yyyy-MM-dd") Date minDate,
			@DateTimeFormat(pattern = "yyyy-MM-dd") Date maxDate) {
		Result<List<FunctionStatisticResult>> result = new Result<>();
		List<FunctionStatisticResult> fsrs = functionStatisticService.getTotalByDate(productId, minDate, maxDate);
		result.setObject(fsrs);
		result.setSuccess(true);
		result.setMessage("查询统计信息成功");
		return new ModelAndView(new MappingJackson2JsonView(), "result", result);
	}
}
